/**
 * 产品服务实现类 - 处理金融服务产品的核心业务逻辑
 *
 * 开发人员：马勇俐
 * 开发时间：2025-11-16 至 2025-11-20
 * 模块职责：实现金融服务产品的创建、查询、更新、删除等核心业务逻辑，与支付订单关联处理
 *
 * 技术要点：
 * - 金融产品的完整生命周期管理
 * - 多租户产品数据隔离和管理
 * - 产品状态和分类管理机制
 * - 产品搜索和过滤功能实现
 * - 异常处理和事务管理机制
 *
 * 开发故事：负责产品服务的核心业务逻辑实现，与产品控制器和前端产品页面深度配合，确保金融产品的完整管理和支付集成。
 */
package com.pbl.service.impl;

import com.pbl.common.exception.BizException;
import com.pbl.entity.Enterprise;
import com.pbl.entity.Product;
import com.pbl.repository.EnterpriseRepository;
import com.pbl.repository.ProductRepository;
import com.pbl.service.ProductService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProductServiceImpl implements ProductService {

    private final ProductRepository productRepository;
    private final EnterpriseRepository enterpriseRepository;

    /**
     * 构造产品服务实现
     * @param productRepository 产品数据访问层
     * @param enterpriseRepository 企业数据访问层
     */
    public ProductServiceImpl(ProductRepository productRepository, EnterpriseRepository enterpriseRepository) {
        this.productRepository = productRepository;
        this.enterpriseRepository = enterpriseRepository;
    }

    @Override
    public List<Product> getProductsByEnterprise(Long enterpriseId) {
        return productRepository.findByEnterprise_IdOrderBySortOrderAsc(enterpriseId);
    }

    @Override
    public List<Product> getActiveProductsByEnterprise(Long enterpriseId) {
        return productRepository.findByEnterprise_IdAndStatusOrderBySortOrderAsc(enterpriseId, Product.ProductStatus.ACTIVE);
    }

    @Override
    public Product getProductById(Long id) {
        return productRepository.findById(id).orElseThrow(() -> new BizException(404, "产品不存在"));
    }

    @Override
    public Product getProductByCode(Long enterpriseId, String code) {
        return productRepository.findByEnterprise_IdAndCode(enterpriseId, code)
                .orElseThrow(() -> new BizException(404, "产品不存在"));
    }

    @Override
    public Product createProduct(Long enterpriseId, String code, String name, String description, 
                                String category, java.math.BigDecimal price, String currency) {
        Enterprise enterprise = enterpriseRepository.findById(enterpriseId)
                .orElseThrow(() -> new BizException(404, "企业不存在"));
        
        // 检查产品代码是否已存在
        if (productRepository.findByEnterprise_IdAndCode(enterpriseId, code).isPresent()) {
            throw new BizException(400, "产品代码已存在");
        }
        
        Product product = Product.builder()
                .enterprise(enterprise)
                .code(code)
                .name(name)
                .description(description)
                .category(category)
                .price(price)
                .currency(currency != null ? currency : "CNY")
                .status(Product.ProductStatus.ACTIVE)
                .sortOrder(0)
                .build();
        
        return productRepository.save(product);
    }

    @Override
    public Product updateProduct(Long id, String name, String description, String category, 
                                java.math.BigDecimal price, String currency, Product.ProductStatus status, Integer sortOrder) {
        Product product = getProductById(id);
        
        if (name != null) product.setName(name);
        if (description != null) product.setDescription(description);
        if (category != null) product.setCategory(category);
        if (price != null) product.setPrice(price);
        if (currency != null) product.setCurrency(currency);
        if (status != null) product.setStatus(status);
        if (sortOrder != null) product.setSortOrder(sortOrder);
        
        return productRepository.save(product);
    }

    @Override
    public void deleteProduct(Long id) {
        Product product = getProductById(id);
        product.setStatus(Product.ProductStatus.DISCONTINUED);
        productRepository.save(product);
    }

    @Override
    public List<Product> searchProducts(Long enterpriseId, String keyword) {
        return productRepository.findByEnterpriseIdAndNameContaining(enterpriseId, keyword);
    }

    @Override
    public List<Product> getProductsByCategory(Long enterpriseId, String category) {
        return productRepository.findByEnterprise_IdAndCategoryAndStatusOrderBySortOrderAsc(
                enterpriseId, category, Product.ProductStatus.ACTIVE);
    }
}
